package handler

import (
	"gateway/config"
	"gateway/core"
	"github.com/spyzhov/ajson"
	"go.uber.org/zap"
	"strings"
)

type jsonPathHandler struct {
	name          string
	args          config.Args
	jsonPath      string
	jsonPathValue string
	key           string
}

func newJsonPathHandler(name string) core.Handler {
	return &jsonPathHandler{
		name: name,
		args: config.NewArgs(),
	}
}

func (this *jsonPathHandler) Handler(msg core.Message) bool {
	if this.key != "" && this.key != msg.GetKey() {
		return false
	}
	if this.jsonPath == "" {
		return true
	}
	payload := msg.GetPayload()
	if len(payload) == 0 {
		return false
	}

	root, err := ajson.Unmarshal(payload)
	if err != nil {
		config.Logger.Warn("Parse json error", zap.Error(err))
		return false
	}
	nodes, err := root.JSONPath(this.jsonPath)
	if err != nil || len(nodes) == 0 {
		config.Logger.Warn("Parse json path error", zap.Error(err))
		return false
	}
	node := nodes[0]
	val, err := node.GetString()
	if err != nil {
		config.Logger.Warn("Parse json path error", zap.Error(err))
		return false
	}
	config.Logger.Debug("Parse json path",
		zap.String("jsonPath", this.jsonPath),
		zap.String("value", val),
		zap.Bool("isPass", val == this.jsonPathValue))
	return val == this.jsonPathValue
}

func (this *jsonPathHandler) SetArgs(args config.Args) {
	this.args.SetArgs(args)
}

func (this *jsonPathHandler) Initialize() {
	this.key = this.args.Get(KEY)
	jp := this.args.Get(JSON_PATH)
	if jp != "" {
		jps := strings.Split(jp, EQUAL)
		if len(jps) != 2 {
			config.Logger.Panic("Invalid json path",
				zap.String("name", this.name),
				zap.String("jsonPath", jp))
		}
		this.jsonPath = jps[0]
		this.jsonPathValue = jps[1]
	}
	config.Logger.Info("Initialize JsonPathHandler",
		zap.String("name", this.name),
		zap.String("key", this.key),
		zap.String("jsonPath", this.jsonPath),
		zap.String("jsonPathValue", this.jsonPathValue))
}

func (this *jsonPathHandler) Destroy() {
	config.Logger.Info("Destroy JsonPathHandler", zap.String("name", this.name))
}
